package com.xx.ViewInfo;

import com.xx.hdfs.HdfsInfo;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextArea;
import javafx.scene.control.TreeItem;
import javafx.scene.control.cell.MapValueFactory;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.Path;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

// 作用:用来定位parent.
public class HdfsView {
    //文件详情
    public FileStatus status;
    //TreeItem
    public Map<String, HdfsView> map;
    public TreeItem<HdfsView> item;
    //    tableView
    public StackPane root;
    private TableView<HashMap<String, SimpleStringProperty>> tv;
    private ObservableList<HashMap<String, SimpleStringProperty>> tableList;
    public HashMap<String, SimpleStringProperty> tableMap;
    public Set<String> expend;
    public boolean expendLeaf = false;
    public Path path;
    public HBox viewInfo;

    public HdfsView(FileStatus status, Map<String, HdfsView> map, StackPane root, Set<String> expend) {
        this.expend = expend;
        this.status = status;
        path = status.getPath();
        this.map = map;
        this.root = root;
        tableMap = new HashMap<>();
        item = new TreeItem<>(this);
        initInfo();
    }


//    public HdfsView(String fileName, String filePath, boolean isDirectory, StackPane root, Map<String, HdfsView> map,
//                    Set<String> expend) {
//        this.expend = expend;
//        item = new TreeItem<>(this);
//        this.filePath = filePath;
//        this.fileName = fileName;
//        this.root = root;
//        this.directory = isDirectory;
//        tableMap = new HashMap<>();
//        this.map = map;
//        tableMap.put("fileName", new SimpleStringProperty(fileName));
//        tableMap.put("filePath", new SimpleStringProperty("/" + filePath));
//        tableMap.put("fileType", new SimpleStringProperty(directory ? "目录" : "文件"));
//        item = new TreeItem<>(this);
//        Text t = new Text(fileName);
//        t.setFill(Color.RED);
//        viewInfo = new HBox(t);
//        viewInfo.setStyle("-fx-background-color:grey");
//        viewInfo.setPrefSize(50, 20);
//    }

    //    必须等treeView构建好才能初始化,因为里面的tableList包含leaf.
    public void initTableView() {
        if (status.isDirectory())
            item.expandedProperty().addListener((ob, ov, nv) -> {
//                读取上次打开情况时不触发.
                if (nv && expendLeaf) item.getChildren().forEach(e -> e.setExpanded(false));
//                刷新记录打开情况
                if (nv) expend.add(status.getPath().toString());
                else expend.remove(status.getPath().toString());
            });
        tableList = FXCollections.observableArrayList();
        tableList.add(tableMap);
        item.getChildren().forEach(e -> tableList.add(e.getValue().tableMap));
        tv = new TableView<>(tableList);
        tv.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);

        TableColumn<HashMap<String, SimpleStringProperty>, String> tc_fileName = new TableColumn<>("名称");
        tc_fileName.setCellValueFactory(new MapValueFactory("fileName"));
        tc_fileName.setSortable(false);

        TableColumn<HashMap<String, SimpleStringProperty>, String> tc_filePath = new TableColumn<>("路径");
        tc_filePath.setCellValueFactory(new MapValueFactory("filePath"));
        tc_filePath.setSortable(false);

        TableColumn<HashMap<String, SimpleStringProperty>, String> tc_fileType = new TableColumn<>("类型");
        tc_fileType.setCellValueFactory(new MapValueFactory("fileType"));
        tc_fileType.setSortable(false);

        tv.getColumns().addAll(tc_fileName, tc_filePath, tc_fileType);
    }

    public void onChoice() {
        if (root.getChildren().size() == 0) root.getChildren().add(0, tv);
        else root.getChildren().set(0, tv);
    }

    public boolean onClicks(TextArea area, HdfsInfo hdfs) throws IOException {
        area.clear();
        if (!status.isDirectory()) {
            FSDataInputStream open = hdfs.demo.open(status.getPath());
            BufferedReader reader = new BufferedReader(new InputStreamReader(open));
            String s;
            while ((s = reader.readLine()) != null)
                area.appendText(s + "\n");
            reader.close();
            open.close();
        }
        return status.isDirectory();
    }

    public void initInfo() {
        map.put(status.getPath().toString(), this);

        tableMap.put("fileName", new SimpleStringProperty(status.getPath().getName()));
        tableMap.put("filePath", new SimpleStringProperty(status.getPath().toString()));
        tableMap.put("fileType", new SimpleStringProperty(status.isDirectory() ? "目录" : "文件"));

        initViewInfo();
    }

    private void initViewInfo() {
        viewInfo = new HBox(10);
        viewInfo.setPrefSize(50, 20);
        viewInfo.setAlignment(Pos.BASELINE_LEFT);
        Text name = new Text(status.getPath().getName());
        if (status.isDirectory()) name.setFill(Color.RED);
        else name.setFill(Color.GREEN);
        viewInfo.getChildren().add(name);
        viewInfo.setStyle("-fx-background-color:grey");

        if (!status.isDirectory()) {
            double kb = status.getLen() / 1024.0;
            double mb = kb / 1024;
            double gb = mb / 1024;
            double tb = gb / 1024;
            Text size = new Text(kb + "");
            viewInfo.getChildren().add(size);
        }

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        Text time = new Text(dateFormat.format(status.getModificationTime()));
        Text permissions = new Text(status.getPermission() + "");
        viewInfo.getChildren().addAll(time, permissions);
    }

    public void refreshItem(HdfsInfo hdfs, Path path) {
        status = hdfs.demo.getFileStatus(path);
        this.path = path;
        initInfo();
        item.getChildren().forEach(e -> e.getValue().refreshItem(hdfs,
                new Path(path.toString() + "/" + e.getValue().status.getPath().getName())));
        initTableView();
    }

    @Override
    public String toString() {
        return status.getPath().getName();
    }

    public void refreshExpendInfo() {
        if (expend.contains(status.getPath().toString())) item.setExpanded(true);
    }
}
